package scaladuct

import javax.validation.{ValidationException, ConstraintViolation, Validation, ValidatorFactory}
import actors.Actor
import collection.immutable.List

/**
 * <p>
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: Jun 28, 2010
 * Time: 8:33:27 PM
 */

sealed abstract class MessageFromClient
case class EditedCookie(cookie: AnyRef, pageTO: ConfigPageTO, context: AnyRef) extends MessageFromClient
case class Question(level: Int, subject: String, breakContext: AnyRef) extends MessageFromClient
case class Escape(context: AnyRef) extends MessageFromClient

sealed abstract class MessageFromServer
case class EditCookie(pageTO: ConfigPageTO, cookie: AnyRef, context: AnyRef) extends MessageFromServer
case class ResultStarter[X](starter: Starter[X], context: AnyRef) extends MessageFromServer
case class NoResult(context: AnyRef) extends MessageFromServer
case class AnswerStarter(starter: Starter[_], question: Question, origPageTO: ConfigPageTO, origCookie: AnyRef, context: AnyRef) extends MessageFromServer
case class NoAnswer(question: Question, origPageTO: ConfigPageTO, origCookie: AnyRef, context: AnyRef) extends MessageFromServer

class ConfigPageActor(val firstPage: ConfigPage[_], val client: Actor) extends Actor {
  def act() {
    handleCookie(List(firstPage))
  }

  private def handleCookie(pageStack: List[ConfigPage[_]]) {
    client ! EditCookie(ConfigPageTO(pageStack.head, null), pageStack.head.getCookie, null)

    react {
      case EditedCookie(cookie, pageTO, context) => {
        pageStack.head.consumeRawCookie(cookie) match {
          case NewStarter(starter) => {
            val remainingPages: List[ConfigPage[_]] = pageStack.tail
            if (remainingPages != Nil) {
              client ! AnswerStarter(starter, null, ConfigPageTO(remainingPages.head, null), remainingPages.head.getCookie, context)
              handleCookie(remainingPages)
            } else {
              client ! ResultStarter(starter, context)
            }
          }
          case NextPage(nextPage) => {
            client ! EditCookie(ConfigPageTO(nextPage), nextPage.getCookie, context)
            handleCookie(nextPage :: pageStack.tail)
          }
        }
      }
      case Question(level, subject, context) => {
        handleQuestion(level, subject) match {
          case Some(questionPage) => {
            client ! EditCookie(ConfigPageTO(questionPage), questionPage.getCookie, context)
            handleCookie(questionPage :: pageStack)
          }
          case None => NoAnswer(null, null, null, null) // todo
        }
      }
    }
  }

  protected def handleQuestion(level: Int, question: AnyRef): Option[ConfigPage[_]] = {
    null
  }

}